--[[
Final Fantasy TAS development scripts

Copyright notice for this file:
 Copyright (C) 2010 TheAxeMan

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
--]]

require "auxlib";

--[[

Pause game when you are just about to hit A to start a battle. The script will
hit A and run until you die or finish the round. It reports your hp and enemy
hp afterwards. Edit below to display the proper information.

--]]

--Do the specified control for the specified number of frames or until
--the function returns true. One frame if not specified.
--If numFrames is 0, then the control is set without a frameadvance. But lag
--frames are skipped.
--I don't see any reason _not_ to ignore lag. But make a global switch anyway.
macroPressButtonsIgnoreLag = true
local function pressButtons(inputTable, numFrames, stopFunc)
  if numFrames == 0 then return end;
  if numFrames then
    if numFrames == 0 then
      repeat
        joypad.set(1, inputTable)
        FCEU.frameadvance()
      until not FCEU.lagged()
      frameRewind(1)
      joypad.set(1, inputTable)
    else
      for i=1,numFrames do
        if macroPressButtonsIgnoreLag then
          repeat
            joypad.set(1, inputTable)
            FCEU.frameadvance()
          until not FCEU.lagged()
        else
          joypad.set(1, inputTable)
          FCEU.frameadvance()
        end;
        if stopFunc and stopFunc() then break end;
      end;
    end;
  else
    joypad.set(1, inputTable)
    FCEU.frameadvance()
  end;
end;

local function getEnemyHp(i)
    baseAddress = 0x6bc1
    hpAddress = baseAddress + 20 * i
    return memory.readbyte(hpAddress) + 256*memory.readbyte(hpAddress+1)
end;

local function getEnemyState(i)
    baseAddress = 0x6bc5
    stateAddress = baseAddress + 20 * i
    --iup.Message("results", stateAddress..memory.readbyte(stateAddress))

    if (memory.readbyte(stateAddress) % 16) == 1 then
        return "Dead"
    end;
    return "Alive"
end;

local function getHeroHp(i)
    baseAddress = 0x60CA
    hpAddress = baseAddress + 64 * i
    return memory.readbyte(hpAddress) + 256*memory.readbyte(hpAddress+1)
end;


startState = savestate.object(8)
savestate.save(startState)
emu.speedmode("turbo")

results = {}
resultText = ""

startHp = getHeroHp(1)

for i=0,255 do
    randSeed = memory.readbyte(0x688A)
    FCEU.unpause()
    pressButtons({A=1})
    pressButtons({}, 5)

    --results[randSeed] = memory.readbyte(0x6bfd) + 256 * memory.readbyte(0x6bfe)

    endSeed = memory.readbyte(0x688A)

    --Good for garland
    --print(randSeed.." | "..getEnemyHp(3).." | "..getHeroHp(1) .." "..getHeroHp(2) .." "..getHeroHp(3) .." "..getHeroHp(4) )
    --Good for pirates
    --print(randSeed.." | " ..getEnemyHp(1) .." "..getEnemyHp(2) .." "..getEnemyHp(3) .." "..getEnemyHp(4) .." "..getEnemyHp(5) .." "..getEnemyHp(6) .." "..getEnemyHp(7) .." "..getEnemyHp(8) .." "..getEnemyHp(9).. " | "..getHeroHp(1) .." "..getHeroHp(2) .." "..getHeroHp(3) )
    --Wizards
    --print(randSeed.." | "..getEnemyHp(1).." "..getEnemyHp(2).." | "..getHeroHp(1) .." "..getHeroHp(2) )
    --Astos
    --print(randSeed.." | "..getEnemyHp(3).." | "..getHeroHp(1) )
    --Fiend
    --print(randSeed.." | "..getEnemyHp(1).." | "..getHeroHp(1).." | "..endSeed )
    --Gas/Zombie D
    print(randSeed.." | "..getEnemyState(1).." "..getEnemyState(2).." | "..getHeroHp(1) .." "..endSeed )
    --print(randSeed.." | "..getEnemyState(1).." "..getEnemyState(2).." "..getEnemyState(3).." | "..getHeroHp(1) .." "..endSeed )

    result = {}
    result.seed = randSeed
    result.enemyHp = getEnemyHp(1)
    result.heroHp = getHeroHp(1)
    result.endSeed = endSeed

    results[i] = result

    savestate.load(startState)
    pressButtons({}, 1)
    savestate.save(startState)

end;

print("\n\n")
for i=0,255 do
    --if results[i].heroHp > 0 then
    if results[i].heroHp == startHp then
        print(results[i].seed .." | ".. results[i].enemyHp .." | ".. results[i].heroHp )
    end;
end;

--iup.Message("results", resultText)

FCEU.pause()


